/*
 * Copyright (C) 2010-2011 Comcast Cable.  All Rights Reserved.
 */
package com.hercules.android.receiver.connection.parser.json.itemparsers;

import com.google.gjson.JSONArray;
import com.google.gjson.JSONException;
import com.google.gjson.JSONObject;
import com.google.gjson.JSONValue;
import com.hercules.android.receiver.connection.parser.CommandParsingException;
import com.hercules.android.receiver.connection.parser.MalformedCommandException;

/**
 * Parser for map property.
 * <p>
 * AndroidAssembly2 this class was added in Android Assembly 2
 *
 * @author 7realm
 * @version 1.0
 */
public class MatrixParser extends FieldParser {
    /** Represents matrix size. */
    private static final int MATRIX_SIZE = 4;

    /**
     * Constructor for {@link MatrixParser}.
     */
    public MatrixParser() {
        super(false);
    }

    /**
     * Parses matrix property.
     *
     * @param path the path to value
     * @param json the JSON
     * @param keyName the name of current JSON key
     * @param instance the instance of object, parsed value will be set to it
     * @return the parsed value
     * @throws CommandParsingException if error occurs while parsing
     */
    @Override
    protected Object doParse(StringBuilder path, JSONObject json, String keyName, Object instance)
        throws CommandParsingException {
        try {
            JSONArray jsonArray = json.get(keyName).isArray();

            // process the matrix filed
            if (jsonArray.size() != MATRIX_SIZE * MATRIX_SIZE) {
                throw new MalformedCommandException(
                    "The array length for 'matrix' should be 16, since 'matrix' is a 4*4 matrix.");
            }
            
            boolean stringResult = false;
            
            double[][] matrix = new double[MATRIX_SIZE][MATRIX_SIZE];
            for (int i = 0; i < MATRIX_SIZE; i++) {
                for (int j = 0; j < MATRIX_SIZE; j++) {
                	JSONValue value = jsonArray.get(i * MATRIX_SIZE + j);
                	if (value.isNumber() == null) {
                		stringResult = true;
                		break;
                	}
                    matrix[j][i] = value.isNumber().doubleValue();
                }
            }
            
            if (!stringResult) {
            	return matrix;
            }
            
            String[] sResult = new String[jsonArray.size()];
            for (int i = 0; i < jsonArray.size(); i++) {
            	JSONValue value = jsonArray.get(i);
            	if (value.isNumber() != null) {
            		sResult[i] = "{" + value.toString() + "}";
            	} else {
            		sResult[i] = jsonArray.get(i).isString().stringValue();
            	}
            }
            return sResult;
        } catch (JSONException e) {
            throw new MalformedCommandException("Failed to process 'dimensions' property at JSON '" + json + "'.", e);
        }
    }

}
